package com.grouponmall.service;

import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.tags.BulletList;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.w3c.dom.Document;

import com.grouponmall.model.Deal;

/**
 * 从Groupon拿到的数据中，会有一部分城市目前还没有商品，这样的城市会直接跳过，后面可以考虑改进为记录相应的日志
 * 
 * @author xueqiang.mi
 * @since 2010-5-30
 * @modified 2010-10-10
 */
public class RetrieveFromGroupon extends BaseRetrieveService {

  public static final String URL = "http://www.groupon.com/cities";
  public static final String SOURCE = "Groupon";

  @Override
  public List<Deal> extract(String link) throws Exception {
    List<Deal> deals = new ArrayList<Deal>();
    String apiLink = getLink(link);
    if (apiLink == null) {
      return null;
    }
    // Create document object by using input stream
    Document doc = null;
    try {
      URL url = new URL(apiLink);
      URLConnection conn = url.openConnection();
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      doc = db.parse(conn.getInputStream());
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }

    // Extract information
    Deal deal = GrouponDealParser.extractInfo(doc);
    if (deal != null) {
      deal.setSource(SOURCE);
      deal.setLink(link);
    }

    deals.add(deal);
    return deals;
  }

  /**
   * @param link
   * @return
   */
  private String getLink(String link) {
    if (link.contains("cities") || link.contains("about") || !link.contains("www.groupon.com/")) {
      return null;
    }
    StringBuilder sb = new StringBuilder();
    sb.append("http://www.groupon.com/api/v1/").append(link.substring(link.indexOf("groupon.com/") + 12)).append(
      "deals/");
    return sb.toString();
  }

  @Override
  @SuppressWarnings("serial")
  public NodeList getExpectedLinks(String link) throws ParserException {
    Parser parser = new Parser(link);
    NodeList list = parser.extractAllNodesThatMatch(new NodeFilter() {
      public boolean accept(Node node) {
        if (!(node instanceof BulletList)) {
          return false;
        }

        BulletList bullet = (BulletList) node;
        String clazz = bullet.getAttribute("class");
        if ("no_bullets".equals(clazz)) {
          return true;
        }
        return false;
      }
    });
    list = list.extractAllNodesThatMatch(new NodeFilter() {
      public boolean accept(Node node) {
        if (node instanceof LinkTag) {
          // LinkTag link = (LinkTag) node;
          // if (link.getLink().contains("houston/")) {
          // return false;
          // }
          return true;
        }
        return false;
      }

    }, true);
    return list;
  }

  public String getURL() {
    return URL;
  }

}
